package com.nhncorp.pleiades.fs;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.hadoop.fs.Path;

import com.nhncorp.pleiades.util.FileUtil;

public class LocalFileSystem extends PleiadesFileSystem {

  public LocalFileSystem() throws IOException {
  }

  
  public boolean exists(Path path) {
    File file = new File(path.toString());
    return file.exists();
  }

  
  public boolean mkdirs(Path path) {
    File file = new File(path.toString());
    return file.mkdirs();
  }

  
  public Path[] list(Path path) throws IOException {
    File file = new File(path.toString());
    if (!file.isDirectory())
      return null;

    File[] files = file.listFiles();

    if (files == null) {
      return null;
    }

    Path[] paths = new Path[files.length];
    for (int i = 0; i < files.length; i++) {
      paths[i] = new Path(files[i].getAbsolutePath());
    }

    return paths;
  }

  
  public OutputStream create(Path path) throws IOException {
    File file = new File(path.toString());
    if (file.getParentFile() != null && !file.getParentFile().exists()) {
      if (!file.getParentFile().mkdirs()) {
        if (!file.getParentFile().exists()) {
          throw new IOException("Can't make directory:" + file.getParentFile());
        } else {
          if (!file.getParentFile().mkdirs()) {
            throw new IOException("Can't make directory:"
                + file.getParentFile());
          }
        }
      }
    }
    return new FileOutputStream(file);
  }

  
  public InputStream open(Path path) throws IOException {
    File file = new File(path.toString());
    return new FileInputStream(file);
  }

  
  public void seek(InputStream in, long offset) throws IOException {
    in.skip(offset);
  }

  
  public boolean delete(Path path) throws IOException {
    File file = new File(path.toString());
    boolean result = file.delete();
    if(!result) {
      if(!file.exists()) {
        return true;
      }
      int retry = 0;
      while(retry < 5) {
        try {
          Thread.sleep(500);
        } catch (InterruptedException e) {
          return false;
        }
        result = file.delete();
        if(result) {
          break;
        }
        retry++;
      }
      if(retry >=5 ) {
        return false;
      }
    }
    return result;
  }

  
  public void move(Path targetPath, Path destPath) throws IOException {
    mkdirs(destPath.getParent());
    FileUtil.moveFile(targetPath.toString(), destPath.toString());
  }

  
  public boolean isDirectory(Path path) throws IOException {
    File file = new File(path.toString());
    return file.isDirectory();
  }

  
  public long getLength(Path path) throws IOException {
    File file = new File(path.toString());
    return file.length();
  }

  
  public DataInputStream openDataInputStream(Path path) throws IOException {
    return new DataInputStream(open(path));
  }

  public boolean renameTo(Path targetPath, Path destPath) throws IOException {
    File file = new File(targetPath.toString());
    return file.renameTo(new File(destPath.toString()));
  }
}
